package fr.afcepf.al22.qualite.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import fr.afcepf.al22.qualite.data.util.Al22DataSource;
import fr.afcepf.al22.qualite.entity.Personne;

/**
 * Classe d'implementation de {@link IDaoPersonne}.
 * 
 * @author Stagiaire
 */
public class DaoPersonneImpl implements IDaoPersonne {
    /**
     * Datasource al22.
     */
    private DataSource ds = new Al22DataSource();
    /**
     * Indice du parametre nom pour le prepared statement de la requete dans la
     * methode {@link DaoPersonneImpl#reqAjout}.
     */
    private final int indiceParamNomRequeteAjout = 1;
    /**
     * Indice du parametre mail pour le prepared statement de la requete dans la
     * methode {@link DaoPersonneImpl#reqAjout}.
     */
    private final int indiceParamMailRequeteAjout = 2;
    /**
     * Indice du parametre mdp pour le prepared statement de la requete dans la
     * methode {@link DaoPersonneImpl#reqAjout}.
     */
    private final int indiceParamMdpRequeteAjout = 3;
    /**
     * Indice du parametre naissance pour le prepared statement de la requete
     * dans la methode {@link DaoPersonneImpl#reqAjout}.
     */
    private final int indiceParamNaissanceRequeteAjout = 4;
    /**
     * Indice de la colonne "generated keys" dans le resultset généré par la
     * requete Ajout.
     */
    private final int indiceColonneGeneratedKetReqAjout = 1;

    /**
     * Requete SQL pour la methode {@link DaoPersonneImpl#ajouter(Personne)}.
     */
    private String reqAjout = "INSERT INTO personne (nom,mail,mdp,naissance) VALUES (?,?,?,?)";

    /**
     * Requete de verification de l'adresse mail.
     */
    private final String reqVerifMail ="SELECT p.* FROM personne p WHERE p.mail LIKE ?";
    
    /**
     * Indice du param 'mail' pour la reqVerifMail.
     */
    private final int indiceParamReqVerfiMail = 1;
    
    /**
     * Requete SQL rechercher par nom.
     */
    private final String reqRechercheNom = "SELECT p.* FROM personne p WHERE p.nom LIKE ?";
    /**
     * Indice du param ',om' pour la reqRechercherNom.
     */
    private final int indiceParamReqRechercherNom = 1;
    
    @Override
    public Personne ajouter(Personne paramPers) {
        Connection cnx = null;
        try {
            cnx = ds.getConnection();
            PreparedStatement pstmt = cnx.prepareStatement(reqAjout, PreparedStatement.RETURN_GENERATED_KEYS);
            pstmt.setString(indiceParamNomRequeteAjout, paramPers.getNom());
            pstmt.setString(indiceParamMailRequeteAjout, paramPers.getMail());
            pstmt.setString(indiceParamMdpRequeteAjout, paramPers.getMdp());
            pstmt.setDate(indiceParamNaissanceRequeteAjout, new java.sql.Date(paramPers.getNaissance().getTime()));
            int nbLigne = pstmt.executeUpdate();
            ResultSet rsKey = pstmt.getGeneratedKeys();
            if (nbLigne == 1 && rsKey.next()) {
                paramPers.setId(rsKey.getInt(indiceColonneGeneratedKetReqAjout));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                cnx.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return paramPers;
    }

    @Override
    public List<Personne> rechercher(String paramNom) {
        List<Personne> personnes = new ArrayList<Personne>();
        Connection cnx = null;
        try {
            cnx = ds.getConnection();
            PreparedStatement psmt = cnx.prepareStatement(reqRechercheNom);
            psmt.setString(indiceParamReqRechercherNom, "%"+paramNom+"%");
            ResultSet rs = psmt.executeQuery();
            while (rs.next()) {
                personnes.add(rsToPersonne(rs));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                cnx.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return personnes;
    }

    @Override
    public Personne verifMail(String paramMail) {
        Personne pers = null;
        Connection cnx = null; 
        try {
            cnx = ds.getConnection();
            PreparedStatement psmt = cnx.prepareStatement(reqVerifMail);
            psmt.setString(indiceParamReqVerfiMail, paramMail);
            ResultSet rs = psmt.executeQuery();
            if (rs.next()) {
                pers = rsToPersonne(rs);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                cnx.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return pers;
    }

    /**
     * Methode pour la converion d'une ligne de result set dans une entité Personne. 
     * @param rs le resultSet contenat le ilgne à transformer.
     * @return Entité {@link Personne} crée à partir de la ligne.
     * @throws SQLException En cas d'erreur sur le rs.
     */
    private Personne rsToPersonne(ResultSet rs) throws SQLException {
        Personne pers = null;
        pers = new Personne(rs.getInt("id"),
                rs.getString("nom"),
                rs.getString("mail"),
                rs.getString("mdp"),
                rs.getDate("naissance")
                );
        return pers;
    }

}
